#include <iostream>
#include <string.h>
using std::cout;
using std::endl;
using std::string;

class Person{
public:
    // 构造函数
    //Person();
    Person(const char* name = "", int age = 0);
    // 防止派生类对象被基类指针删除时内存泄漏
    virtual ~Person();

    // 复制操作
    Person(const Person&);
    Person& operator=(const Person&);

    // 成员函数
    virtual void display(void);   // 虚函数

private:
    char* _name;
    int _age;
};

class Employee: public Person{
public:
    // 构造函数
    Employee(const char* name, int age, const char* section, int wage);
    ~Employee() override;
    Employee(const Employee&);             // 派生类拷贝构造
  
    // 复制函数
    Employee& operator=(const Employee&);  // 派生类拷贝赋值

    // 成员函数
    void display(void) override;
    static double avgWage(Employee[], size_t);    // 平均工资计算
private:
    char* _section;
    int _wage;

};

// 默认参数不能写在两处，可以在声明处指定，定义时不再写默认参数
// Person::Person(const char* name = "", int age = 0)
Person::Person(const char* name, int age)
    :_name(new char[strlen(name) + 1]())
    ,_age(age){
         strcpy(_name, name);
    }

Person::~Person(){
    delete[] _name;
}

Person::Person(const Person& rhs)
    :_name(new char[strlen(rhs._name) + 1]())
    ,_age(rhs._age){
    strcpy(_name, rhs._name);
}

Person& Person::operator=(const Person& rhs){
    if(this != &rhs){
        delete [] _name;
        char * temp = new char[strlen(rhs._name) + 1]();
        strcpy(temp, rhs._name);
    }
    return *this;
}

void Person::display(void){
    cout << "name :" << _name << "\n" 
        << "age :" << _age << endl;
}


Employee::Employee(const char* name, int age, const char* section, int wage)
    :Person(name, age)
    ,_section(new char[strlen(section) + 1]())
    ,_wage(wage){
    strcpy(_section, section);
}

Employee::~Employee(){
    delete[] _section;   // 这里由于析构函数设置为虚函数，会自动调用Person
}

Employee::Employee(const Employee& rhs)
    :Person(rhs)
    ,_section(new char[strlen(rhs._section) + 1]())
    ,_wage(rhs._wage){
    strcpy(_section, rhs._section);
}
  
Employee& Employee::operator=(const Employee& rhs){
    if(this != &rhs){
        Person::operator=(rhs);     // 调用基类赋值
       
        delete []_section;
        _section = new char[strlen(rhs._section) + 1]();
        strcpy(_section, rhs._section);
        _wage = rhs._wage;
    }
    return *this;
}

void Employee::display(void){
    Person::display();
    cout << "section:" << _section << "\n"
        << "wage:" << _wage << endl;
}

double Employee::avgWage(Employee arr[], size_t n){
    double sum = 0;
    for(size_t i = 0; i < n; ++i){
        sum += arr[i]._wage;
    }
    return sum / n;
}

void test() {
    cout << "===== 基础构造/析构测试 =====" << endl;
    Employee em1("张三", 25, "技术部", 8000);  // 栈对象自动析构
    em1.display();

    cout << "\n===== 拷贝构造测试 =====" << endl;
    Employee em2 = em1;  // 调用拷贝构造函数
    em2.display();

    cout << "\n===== 拷贝赋值测试 =====" << endl;
    Employee em3("李四", 30, "销售部", 5000);
    em3 = em1;  // 调用拷贝赋值运算符
    em3.display();

    cout << "\n===== 多态删除测试 =====" << endl;
    Person* p = new Employee("王五", 28, "人事部", 6000);
    p->display();  // 多态调用
    delete p;      // 验证虚析构链

    cout << "\n===== 平均工资测试 =====" << endl;
    Employee staff[] = {
        Employee("A", 22, "部1", 3000),
        Employee("B", 25, "部2", 4000),
        Employee("C", 30, "部3", 5000)
    };
    cout << "平均工资: " 
         << Employee::avgWage(staff, 3) << endl;
}

int main() {
    test();
    return 0;
}


